package com.hhxy.aspect;

import com.alibaba.fastjson.JSON;
import com.hhxy.annotation.SystemLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

/**
 * @author ghp
 * @date 2023/4/29
 * @title
 * @description
 */
@Component
@Aspect
@Slf4j
public class SystemLogAspect {


    /**
     * 切入点
     */
    @Pointcut("@annotation(com.hhxy.annotation.SystemLog))")
    public void pt() {

    }


    /**
     * 环绕通知
     *
     * @param joinPoint 被增强的方法所封装的对象
     * @return
     */
    @Around("pt()")
    public Object printLog(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result;
        try {
            // 执行前置通知（目标方法执行前打印日志）
            handleBefore(joinPoint);
            // 注意：不要try catch，不然controller层的异常都被切面捕捉到了
            // 执行目标方法，同时获取切入连所在的类名和方法名
            result = joinPoint.proceed();
            String className = joinPoint.getTarget().getClass().getSimpleName();
            String methodName = joinPoint.getSignature().getName();
            log.info(className + "." + methodName + "被执行");
            // 打印出参
            log.info("Response       : {}", JSON.toJSONString(result));
        } finally {
            // 结束后换行(System.lineSeparator()动态换行，linux和Windows的换行符不一样)
            log.info("=======End=======" + System.lineSeparator());
            System.out.println(System.lineSeparator());
            System.out.println(System.lineSeparator());
            System.out.println(System.lineSeparator());
        }
        return result;
    }

    /**
     * 前置通知
     */
    private void handleBefore(ProceedingJoinPoint joinPoint) {
        // 获取增强方法上的注解对象
        SystemLog systemLog = this.getSystemLog(joinPoint);
        log.info("=======Start=======");
        // 打印描述信息
        log.info("BusinessName   : {}", systemLog.businessName());
    }

    /**
     * 获取增强方法上的注解对象
     *
     * @param joinPoint
     * @return
     */
    private SystemLog getSystemLog(ProceedingJoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        SystemLog systemLog = methodSignature.getMethod().getAnnotation(SystemLog.class);
        return systemLog;
    }
}
